package org.dream.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.lang.StringUtils;

/**
 * Double 的工具包,主要用于金额之类要求精确数字的场合
 * 
 * @author qiuriyuchen E-mail:panpan_001@126.com
 */
public class DoubleUtil {
	/** 进制为10进制 */
	private static final int DEF_DIV_SCALE = 10;

	public static Double scale2(Double v) {
		if (v == null) {
			return null;
		}
		DecimalFormat df = new DecimalFormat("#.00");
		return Double.parseDouble(df.format(v));

	}

	// 得到整数位数
	public static int getIntNum(Double value) {
		DecimalFormat df = new DecimalFormat("#");
		String str = df.format(value).replaceAll("-", "");
		return str.length();
	}

	// 是否有有效
	public static void main(String[] args) {
		Double double1 = -3.126;
		System.out.println("changeDecimal-3.126" + DoubleUtil.changeDecimal(-3.126, 2));
		System.out.println("changeDecimal103.126" + DoubleUtil.changeDecimal(103.126, 2));
		System.out.println("changeDecimal1043.1" + DoubleUtil.changeDecimal(1043.1, 2));
		System.out.println(DoubleUtil.scale2(double1));

		System.out.println("0.1*0.1=" + DoubleUtil.mul(0.1, 0.1));
		System.out.println("1.0-0.1=" + DoubleUtil.sub(1.0, 0.1));
		System.out.println("0.1+0.1=" + DoubleUtil.add(0.1, 0.1));
		System.out.println(DoubleUtil.getIntNum(double1));
		System.out.println(DoubleUtil.toDecimalString("4444564321.2135", 2));
	}

	/**
	 * 四舍五入
	 * 
	 * @param value
	 *            值
	 * @param num
	 *            小数位数
	 * @return
	 */
	public static Double changeDecimal(Double value, int num) {
		if (null == value) {
			return null;
		}
		BigDecimal b = new BigDecimal(value);
		double v = b.setScale(num, BigDecimal.ROUND_HALF_UP).doubleValue();// 表明四舍五入，保留两位小数
		return v;
	}

	public static Double changeDecimal(Double value, int num, int roundingMode) {
		if (null == value) {
			return null;
		}
		BigDecimal b = new BigDecimal(value);
		double v = b.setScale(num, roundingMode).doubleValue();// 表明四舍五入，保留两位小数
		return v;
	}

	/** 得到不以科学计数数据格式的字符串 */
	public static String toDecimalString(String str, int decimal) {
		if (StringUtils.isEmpty(str)) {
			return "";
		}
		return DoubleUtil.toDecimalString(Double.valueOf(str.trim()), decimal);
	}

	/** 得到不以科学计数数据格式的字符串 */
	public static String toDecimalString(Double num, int decimal) {
		if (num == null) {
			return "";
		}
		String str = "" + num;
		String formatStr = "#.";
		for (int i = 0; i < decimal; i++) {
			formatStr += "0";
		}
		DecimalFormat df = new DecimalFormat(formatStr);
		try {
			str = "" + df.format(num);

		} catch (Exception e) {

		}
		return str;
	}

	/** 得到以,号分隔的计数数据格式的字符串 */
	public static String toSplitDecimalString(Double num, int decimal) {
		if (num == null) {
			return "";
		}
		String str = "" + num;
		String formatStr = "###,###.";
		for (int i = 0; i < decimal; i++) {
			formatStr += "0";
		}
		DecimalFormat df = new DecimalFormat(formatStr);
		try {
			str = "" + df.format(num);

		} catch (Exception e) {

		}
		return str;
	}

	/** 得到以,号分隔的计数数据格式的字符串 */
	public static String toSplitDecimalString(String str, int decimal) {
		if (StringUtils.isEmpty(str)) {
			return "";
		}
		return DoubleUtil.toSplitDecimalString(Double.valueOf(str.trim()), decimal);
	}

	/**
	 * 两个Double数相加
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double add(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.add(b2).doubleValue();
	}

	public static Double add(Double v1, Double v2, int num) {
		return changeDecimal(add(v1, v2), num);
	}

	/**
	 * 两个Double数相减
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double sub(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 两个double相减,并把结果设置精度
	 * 
	 * @param v1
	 * @param v2
	 * @param num
	 * @return
	 */
	public static Double sub(Double v1, Double v2, int num) {
		return changeDecimal(sub(v1, v2), num);
	}

	/**
	 * 两个Double数相乘
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double mul(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 两个double相乘,并把结果设置精度
	 * 
	 * @param v1
	 * @param v2
	 * @param num
	 * @return
	 */
	public static Double mul(Double v1, Double v2, int num) {
		return changeDecimal(mul(v1, v2), num);
	}

	/**
	 * 两个Double数相除
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double div(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 两个Double数相除，并保留scale位小数
	 * 
	 * @param v1
	 * @param v2
	 * @param scale
	 * @return Double
	 */
	public static Double div(Double v1, Double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

}
